#
# initscripts functions
#
# Special for Archlive   Base on initscripts-2010.07

#------------------- Archlive changed -------------------------
. /usr/lib/liblinuxlive
# lang:
export msg_lang
if [ "$cn" = "y" ]; then
	msg_lang="cn"
#elif [ "$en" = "y" ]; then
#	msg_lang="en"
#elif [ "${LOCALE%_*}x" = "zhx" ]; then
#	msg_lang="cn"
else
	msg_lang="en"
fi
#---------------------------------------------------------------

# width:

STAT_COL=80
if [ ! -t 1 ]; then
  USECOLOR=""

# stty will fail when stdin isn't a terminal
elif [ -t 0 ]; then
  STAT_COL="$(/bin/stty size)"
  # stty gives "rows cols"; strip the rows number, we just want columns
  STAT_COL="${STAT_COL##* }"

else
  # is /usr/share/terminfo already mounted, and TERM recognized?
  /bin/tput cols &>/dev/null
  if [ $? -eq 0 ]; then
    STAT_COL=$(/bin/tput cols)
  fi
fi
if [ "0$STAT_COL" -eq 0 ]; then
  # if output was 0 (serial console), set default width to 80
  STAT_COL=80
  USECOLOR=""
fi

# we use 13 characters for our own stuff
STAT_COL=$(($STAT_COL - 13))

# disable colors on broken terminals
TERM_COLORS="$(/bin/tput colors 2>/dev/null)"
if [ $? = 3 ]; then
	TERM_COLORS=8
elif [ -n "${TERM_COLORS}" ]; then
	case "${TERM_COLORS}" in
		*[!0-9]*)
			USECOLOR=""
			;;
		*)
			[ "${TERM_COLORS}" -lt 8 ] && USECOLOR=""
			;;
	esac
else
	USECOLOR=""
fi
unset TERM_COLORS

# clear the TZ envvar, so daemons always respect /etc/localtime
unset TZ

#------------------- Archlive changed -------------------------
# 
# colors:
if [ "$USECOLOR" = "YES" -o "$USECOLOR" = "yes" ]; then
	C_MAIN="\033[1;37;40m"      # main text 白色
	C_OTHER="\033[1;34;40m"     # prefix & brackets  蓝色
	C_SEPARATOR="\033[1;30;40m" # separator 灰色

	C_BUSY="\033[0;36;40m"      # busy  淡蓝色
	C_FAIL="\033[1;31;40m"      # failed  红色
	#C_DONE="\033[1;37;40m"      # completed  白色
	C_DONE="\033[1;32;40m"      # completed  绿色
	C_BKGD="\033[1;35;40m"      # backgrounded 紫色

	C_H1="\033[1;37;40m"        # highlight text 1  白色
	C_H2="\033[1;36;40m"        # highlight text 2  淡蓝色
	C_H3="\033[1;33;40m"        # highlight text 2  黄色

	C_CLEAR="\033[1;0m"
fi
#---------------------------------------------------------------

if [ -t 1 ]; then
	SAVE_POSITION="\033[s"
	RESTORE_POSITION="\033[u"
	DEL_TEXT="\033[$(($STAT_COL+4))G"
else
	SAVE_POSITION=""
	RESTORE_POSITION=""
	DEL_TEXT=""
fi

# prefixes:

PREFIX_REG="::"
PREFIX_HL=" >"

# functions:

deltext() {
	printf "${DEL_TEXT}"
}

printhl() {
	printf "${C_OTHER}${PREFIX_HL} ${C_H1}${1}${C_CLEAR} \n"
}

printsep() {
	printf "\n${C_SEPARATOR}   ------------------------------\n"
}

stat_bkgd() {
	printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} "
	deltext
	if [ "${msg_lang}" = "cn" ]; then
		printf "   ${C_OTHER}[${C_BKGD}后台${C_OTHER}]${C_CLEAR} "
	else
		printf "   ${C_OTHER}[${C_BKGD}BKGD${C_OTHER}]${C_CLEAR} "
	fi
}

stat_busy() {
	printf "${C_OTHER}${PREFIX_REG} ${C_MAIN}${1}${C_CLEAR} "
	printf "${SAVE_POSITION}"
	deltext
	if [ "${msg_lang}" = "cn" ]; then
		printf "   ${C_OTHER}[${C_BUSY}忙碌${C_OTHER}]${C_CLEAR} "
	else
		printf "   ${C_OTHER}[${C_BUSY}BUSY${C_OTHER}]${C_CLEAR} "
	fi
}

stat_append() {
	printf "${RESTORE_POSITION}"
	printf -- "${C_MAIN}${1}${C_CLEAR}"
	printf "${SAVE_POSITION}"
}

stat_done() {
	deltext
	if [ "${msg_lang}" = "cn" ]; then
		printf "   ${C_OTHER}[${C_DONE}完成${C_OTHER}]${C_CLEAR} \n"
	else
		printf "   ${C_OTHER}[${C_DONE}DONE${C_OTHER}]${C_CLEAR} \n"
	fi
}

stat_fail() {
	deltext
	if [ "${msg_lang}" = "cn" ]; then
		printf "   ${C_OTHER}[${C_FAIL}失败${C_OTHER}]${C_CLEAR} \n"
	else
		printf "   ${C_OTHER}[${C_FAIL}FAIL${C_OTHER}]${C_CLEAR} \n"
	fi
}


stat_die() {
	retval=1
	[ "$1" = "" ] || retval=$1
	stat_fail
	exit $retval
}

status() {
	stat_busy "$1"
	shift
	$* >/dev/null 2>&1
	if [ $? -eq 0 ]; then
		stat_done
		return 0
	else
		stat_fail
		return 1
	fi
}

#  usage : in_array( $needle, $haystack )
# return : 0 - found
#          1 - not found
# Copied from makepkg
in_array() {
  local needle=$1; shift
  [ -z "$1" ] && return 1 # Not Found
  local item
  for item in "$@"; do
    local c="${item:0:1}"
    if [ "x$c" = "x@" ]; then
      item="${item:1}"
    fi
    [ "$item" = "$needle" ] && return 0 # Found
  done
  return 1 # Not Found
}

# daemons:

add_daemon() {
	[ -d /var/run/daemons ] || /bin/mkdir -p /var/run/daemons
	/bin/touch /var/run/daemons/$1
}

rm_daemon() {
	/bin/rm -f /var/run/daemons/$1
}

ck_daemon() {
	[ -f /var/run/daemons/$1 ] && return 1
	return 0
}

ck_depends() {
	for daemon in $@; do
		if ck_daemon $daemon; then
			/etc/rc.d/$daemon start
		fi
	done
}

start_daemon() {
	/etc/rc.d/$1 start
}

start_daemon_bkgd() {
	if [ "${msg_lang}" = "cn" ]; then
		stat_bkgd "启动后台程序 $1"
	else
		stat_bkgd "Starting $1"
	fi
	if [ -x /etc/rc.d/$1 ]; then
		(/etc/rc.d/$1 start) &>/dev/null &
	fi
}

stop_daemon() {
	/etc/rc.d/$1 stop
}

# Status functions
status_started() {
  deltext
  if [ "${msg_lang}" = "cn" ]; then
  	echo -ne "$C_OTHER[${C_STRT}已启动.$C_OTHER]$C_CLEAR "
  else
  	echo -ne "$C_OTHER[${C_STRT}STARTED$C_OTHER]$C_CLEAR "
  fi
}

status_stopped() {
  deltext
  if [ "${msg_lang}" = "cn" ]; then
  	echo -ne "$C_OTHER[${C_STRT}已停止.$C_OTHER]$C_CLEAR "
  else
  	echo -ne "$C_OTHER[${C_STRT}STOPPED$C_OTHER]$C_CLEAR "
  fi
}


ck_status() {
  ck_daemon $1
  if [ $? -eq 1 ]; then
    status_started
  else
    status_stopped
  fi		
}

###############################
# Custom hooks in initscripts #
###############################
# Hooks can be used to include custom code in various places in the rc.* scripts
#
# Define a hook function in a functions.d file using:
#  function_name() {
#    ...
#  }
#  add_hook hook_name function_name
# It is allowed to register several hook functions for the same hook
# Is is also allowed to register the same hook function for several hooks
#
# Currently, the following hooks exist:
# sysinit_start: at the beginning of rc.sysinit
# multi_start: at the beginning of rc.multi
# single_start: at the beginning of rc.single
# shutdown_start: at the beginning of rc.shutdown
# sysinit_end: at the end of rc.sysinit
# multi_end: at the end of rc.multi
# single_end: at the end of rc.single
# sysinit_udevlaunched: after udev has been launched in rc.sysinit
# single_udevlaunched: after udev has been launched in rc.single
# sysinit_udevsettled: after uevents have settled in rc.sysinit
# single_udevsettled: after uevents have settled in rc.single
# sysinit_premount: before local filesystems are mounted, but after root is mounted read-write in rc.sysinit
# shutdown_prekillall: before all processes are being killed in rc.shutdown
# single_prekillall: before all processes are being killed in rc.single
# shutdown_postkillall: after all processes have been killed in rc.shutdown
# single_postkillall: after all processes have been killed in rc.single
# shutdown_poweroff: directly before powering off in rc.shutdown
#
# Make sure to never override the add_hook and run_hook functions via functions.d

declare -A hook_funcs

add_hook() {
	[ -z "$1" -o -z "$2" ] && return 1
	hook_funcs["$1"]="${hook_funcs["$1"]} $2"
}

run_hook() {
	local func

	[ -z "$1" ] && return 1
	for func in ${hook_funcs["$1"]}; do
		${func}
	done
}

#------------------- Archlive changed -------------------------
# 保存live系统使用过程中的修改
# $1 xz 或者 merge 
# xz 将修改采用xz压缩到到存储目录下
# merge 将修改合并到overlay中
# $2 存储目录
action_save ()
{
    SAVEPATH=$2
    if [ "x$SAVEPATH" = "x" ]; then
	if [ "${msg_lang}" = "cn" ]; then
		echo "没有指定保存路径且默认的保存路径不可用，放弃保存!"
	else
		echo "No savepath determined or unusable, quit for saving changes!"
	fi
	return 1
    fi

    excludes=".live .wh* mnt media dev proc sys tmp var/run"
    if [ "$1" = "xz" ]; then
	EXCLUDES=""
	for i in $excludes; do
		EXCLUDES="${EXCLUDES} --exclude=$i"
	done
	pushd /.live/changes
	tar -cJpf ${SAVEPATH}/$(date +%Y%m%d).tar.xz ./ ${EXCLUDES}
	popd
    elif [ "$1" = "merge" ]; then
	save="bin boot etc home lib opt root sbin srv usr var"
	mkdir /tmp/save_tmp
	mount -t aufs -o br:$/.live/overlay=ro aufs /tmp/save_tmp >>${LOG}
	mount -t aufs -o remount,add:0:$/.live/changes=ro aufs /tmp/save_tmp >>${LOG}
	mksquashfs /tmp/save_tmp  ${SAVEPATH}/$overlayname.new -noappend >>${LOG}
	#umount -l 
    fi
}

doeject ()
{
    if [ -n "${ejectdev}" ]; then
	if [ "${msg_lang}" = "cn" ]; then
		echo "弹出$LIVECDNAME CD"
	else
		echo "Ejecting $LIVECDNAME CD"
	fi
        mount -n -o remount,rw /
        # Remove the boot medium from /etc/mtab so that eject works
        sed "/ \/.livesys\/medium / d" -i /etc/mtab
        eject ${ejectdev}
        mount -n -o remount,ro /
        echo "========================================"
        echo "It's safe to switch the computer off now"
        echo -ne "Press Enter to continue"
        read junk
    fi

    # This shouldn't be needed, but better safe than sorry?
    sync
}

sysinit_premount_archlive() {
    if [ "${msg_lang}" = "cn" ]; then
	status "Archlive 预启动"
    else
	status "Archlive sysinit_premount hook"
    fi
    # Rebuild /etc/mtab
    grep "^aufs */ " /proc/mounts               >/etc/mtab.new
    grep "^unionfs */ " /proc/mounts            >>/etc/mtab.new
    grep "^tmpfs */.livesys " /proc/mounts      >>/etc/mtab.new
    if [ -d /.livesys/medium/larch ]; then
        grep " /.livesys/medium " /proc/mounts  >>/etc/mtab.new
    fi
    grep -v "^rootfs " /etc/mtab                >>/etc/mtab.new
    mv /etc/mtab.new /etc/mtab

    # Add disk partitions to /etc/fstab
    #fstab_update /
}
#add_hook sysinit_premount sysinit_premount_archlive

sysinit_end_archlive() {
    # Allow setting up of xorg.conf before xorg is started
    status "Archlive sysinit_end hook"
    [ -x /etc/X11/xinit/xorg.conf.set ] && /etc/X11/xinit/xorg.conf.set
}
#add_hook sysinit_end sysinit_end_archlive


# rc.shutdown运行到结束所有进程后
shutdown_postkillall_archlive() {
    status "Archlive shutdown_postkillall hook"
    if ! [ -f /.livesys/saveclock ]; then
        # This will prevent the hardware clock from being set
        HARDWARECLOCK='LIVE'
    fi
}
#add_hook shutdown_postkillall shutdown_postkillall_archlive

input_path () {
    if [ "${msg_lang}" = "cn" ]; then
	echo "请输入需要保存修改的位置:"
	echo "---------------------------------"
	echo " <回车>: 放弃"
	echo "预保存的位置 <回车>: 将修改保存到指定的位置"
	read -p "输入地址:" path
	echo $path
    else
	echo "Please input the path for saving changes:"
	echo "---------------------------------"
	echo " <Enter>: Quit for saving changes"
	echo "path <Enter>: Saving changes to \"path\""
	read -p "Path?:" path
	echo $path
    fi
}

check_savepath() {
    if [ "x$1" = "x" ]; then
	return 1
    else
	savepath=$1
	touch $savepath/empty 2>/dev/null && rm -f $savepath/empty 2>/dev/null
	if [ $? -ne 0 ]; then
		if [ "${msg_lang}" = "cn" ]; then
			echo "警告: $savepath 不可写, 因此无法保存修改！"
			echo
			check_savepath $(input_path)
		else
			echo "Warn: $savepath not used or not writable, Can't saving changes！"
			echo
			check_savepath $(input_path)
		fi
    	else
		SAVEPATH=$savepath
		return 0
	fi
    fi
}

# 全局参数XZ_PATH MERGE_PATH 来自于/usr/lib/liblinuxlive
shutdown_poweroff_archlive() {

    export SAVEPATH
    if [ "${msg_lang}" = "cn" ]; then
	echo "===== 是否保存修改? ====="
	echo 
	echo "请输入选项:"
	echo "----------------------------"
	echo "   <回车>: 不保存"
	echo " 1 <回车>: 保存修改为xz压缩包"
	echo " 2 <回车>: 合并修改到overlay"
	read -p "选择? :" select
    else
	echo "===== Save Changes? ====="
	echo 
	echo "Select:"
	echo "----------------------------"
	echo "   <Enter>: Don't Saving Changes"
	echo " 1 <Enter>: Saving Changes as .xz on addon dir"
	echo " 2 <Enter>: Merge Changes input Overlay"
	read -p "Choice? :" select
    fi
    case ${select} in
	1) if check_savepath $XZ_PATH ; then
		action_save xz $SAVEPATH
	   fi
	   ;;
	2) if check_savepath $MERGE_PATH ; then
		action_save merge $SAVEPATH
	   fi
	   ;;
	*) ;;
    esac

    # Eject CD/DVD
    doeject
}
add_hook shutdown_poweroff shutdown_poweroff_archlive
#---------------------------------------------------------------

# Function for setting console font if required
set_consolefont() {
    if [ -n "$CONSOLEFONT" ]; then
	stat_busy "Loading Console Font: $CONSOLEFONT"
	#CONSOLEMAP in UTF-8 shouldn't be used
	if [ -n "$CONSOLEMAP" ] && echo "$LOCALE" | /bin/grep -qi utf ; then
		CONSOLEMAP=""
	fi
	for i in /dev/tty[0-9]*; do
		if [ -n "$CONSOLEMAP" ]; then
			/usr/bin/setfont -m $CONSOLEMAP $CONSOLEFONT -C ${i} >/dev/null 2>&1
		else
			/usr/bin/setfont $CONSOLEFONT -C ${i} >/dev/null 2>&1
		fi
	done
	if [ $? -ne 0 ]; then
		stat_fail
	else
		if [ -n "$CONSOLEMAP" ]; then
			echo 'if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\033(K"; fi' >>/etc/profile.d/locale.sh
		fi
		stat_done
	fi
    fi
}



# Source additional functions at the end to allow overrides
for f in /etc/rc.d/functions.d/*; do
  if [ -e $f ]; then
    . $f
  fi
done

# End of file
# vim: set ft=sh sw=2 ts=2 et:
